package com.example.text.diyviews

import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.text.Editable
import android.text.TextWatcher
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import android.widget.FrameLayout
import com.example.text.R
import com.example.text.utils.ToastUtils


/**
 * @author yaotianxue
 * @description
 * @date 2025/5/15
 */
class VerifyCodeView : FrameLayout,View.OnClickListener {
    private val codeViewList: List<VerifyCodeItemView>
    private val et: EditText
    private val tvPaste: View
    private var inputText = ""
    private var codeLength = 0
    private var onInputVerifyCodeCompleted: ((smsCode: String) -> Unit)? = null //输入完成回调



    constructor(context: Context) : this(context, null)
    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : this(context, attrs, defStyleAttr,0)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes){
        val parentView = LayoutInflater.from(context).inflate(R.layout.layout_verify_code_view, this) as ViewGroup
        parentView.setOnClickListener(this)
        codeViewList = listOf(
            parentView.findViewById(R.id.code_1),
            parentView.findViewById(R.id.code_2),
            parentView.findViewById(R.id.code_3),
            parentView.findViewById(R.id.code_4),
            parentView.findViewById(R.id.code_5),
            parentView.findViewById(R.id.code_6)
        )
        tvPaste = parentView.findViewById<View>(R.id.tv_paste)
        et = parentView.findViewById(R.id.et_input)
        codeLength = codeViewList.size
        parentView.setOnLongClickListener {
            if (tvPaste.visibility == View.VISIBLE) {
                tvPaste.visibility = View.GONE
            } else {
                tvPaste.visibility = View.VISIBLE
            }
            true
        }
        //粘贴
        tvPaste.setOnClickListener {
            paste()
            tvPaste.visibility = View.GONE
        }
        //编辑
        et.addTextChangedListener(VerifyTextWatcher())
        et.setOnFocusChangeListener { v, hasFocus ->
            if (hasFocus) {
                if (inputText.length < codeViewList.size) {
                    codeViewList[inputText.length].setFocus(true)
                }
            } else {
                codeViewList.forEach {
                    it.setFocus(false)
                }
            }
        }
        et.setOnEditorActionListener { _, i, _ ->
            if (i == EditorInfo.IME_ACTION_DONE) {
                hideSoftKeyBoard()
                this.onInputVerifyCodeCompleted?.invoke(inputText)
            }
            true
        }

    }
    fun clear() {
        et.text.clear()
    }

    /**
     * 自定义view，当window解绑不用的时，取消所有焦点
     */
    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        codeViewList.forEach {
            it.setFocus(false)
        }
    }

    private fun paste() {
        val code = getClipData()
        //校验验证码长度
        if (code?.length == 6) {
            et.setText("")
            et.setText(getClipData())
        } else {
            ToastUtils.showShort(context, "粘贴内容错误")
        }
    }

    /**
     * 获得剪贴板的内容
     */
    private fun getClipData(): String? {
        //获取系统剪贴板服务
        val clipboardManager: ClipboardManager? = context.getSystemService(Context.CLIPBOARD_SERVICE) as? ClipboardManager
        if (null != clipboardManager) {
            // 获取剪贴板的剪贴数据集
            val clipData: ClipData? = clipboardManager.getPrimaryClip()
            if (null != clipData && clipData.getItemCount() > 0) {
                // 从数据集中获取（粘贴）第一条文本数据
                val item: ClipData.Item = clipData.getItemAt(0)
                if (null != item) {
                    return item.getText().toString()
                }
            }
        }
        return null
    }

    fun setOnInputVerifyCodeCompleted(l: (smsCode: String) -> Unit) {
        this.onInputVerifyCodeCompleted = l
    }


    inner class VerifyTextWatcher:TextWatcher {
        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {

        }

        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
            inputText = s?.toString() ?: ""
            if (before == 0) {
                //焦点后移
                if (inputText.length < codeViewList.size)
                    codeViewList[inputText.length].setFocus(true)
                //取消前面的焦点
                if (inputText.isNotEmpty()) {
                    codeViewList[inputText.length - count].setFocus(false)
                }
                //设置输入的内容
                repeat(inputText.length) {
                    codeViewList[it].setNumber(inputText[it].toString())
                }

            } else {
                //焦点前移
                if (inputText.length >= 6) return
                codeViewList[inputText.length].setFocus(true)
                //取消前一位焦点
                if (inputText.length + before < codeViewList.size) {
                    codeViewList[inputText.length + before].setFocus(false)

                }
                //清除输入内容
                repeat(before) {
                    codeViewList[inputText.length + it].setNumber("")
                }
            }
            if (inputText.length == codeLength) {
                //自动触发输入完成
                hideSoftKeyBoard()
                this@VerifyCodeView.onInputVerifyCodeCompleted?.invoke(inputText)
            }
        }

        override fun afterTextChanged(s: Editable?) {

        }
    }

    override fun onClick(v: View?) {
        et.requestFocus()
        showSoftKeyBoard()

    }
    fun showSoftKeyBoard() {
        val manager: InputMethodManager = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        postDelayed({
            et.requestFocus()
            manager.showSoftInput(et, InputMethodManager.RESULT_UNCHANGED_SHOWN)
        }, 300)
    }
    private fun hideSoftKeyBoard() {
        et.clearFocus()
        val manager: InputMethodManager = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        manager.hideSoftInputFromWindow(this.windowToken, 0)
    }
}